App.require(["matrix3"], function (matrix3) {
    var Matrix3 = matrix3.Matrix3;
    App.defineWidget("text", {
        render: function (ctx) {
            ctx.save();
            var style = this.style;
            ctx.globalAlpha = style.opacity;
            var shadowObj = App.Widget.strToShadow(style.shadow);
            if (shadowObj) {
                ctx.shadowOffsetX = shadowObj.x;
                ctx.shadowOffsetY = shadowObj.y;
                ctx.shadowBlur = shadowObj.blur;
                ctx.shadowColor = shadowObj.color;
            }
            var transforms = App.Widget.strToTransform(style.transform);
            if (transforms) {
                for (var i = 0; i < transforms.length; i++) {
                    var tranObj = transforms[i];
                    ctx[tranObj.key].apply(ctx, tranObj.param);
                }
            }
            ctx.textAlign = style.align;
            ctx.textBaseline = style.baseline;
            ctx.font = style.font;
            if (style.fill) {
                ctx.fillStyle = style.fill;
                ctx.fillText(style.text, style.x, style.y);
            }
            if (style.stroke) {
                ctx.strokeStyle = style.stroke;
                ctx.strokeText(style.text, style.x, style.y);
            }
            ctx.restore();
        },
        isPointIn: function (ctx, x, y) {
            var style = this.style;
            ctx.font = style.font;
            var width = ctx.measureText(style.text).width;
            var height = App.Widget.getFontSize(style.font) * 1.5;
            var rect = this.getRect(width + 10, height + 6);
            ctx.beginPath();
            ctx.rect(rect.x, rect.y, rect.width, rect.height);
            return ctx.isPointInPath(x, y);
        },
        getRect: function (width, height) {
            var style = this.style, x = style.x - 5, y = style.y - 3;
            var lt = x, tp = y;
            switch (style.align) {
                case App.TextAlignOption.CENTER: lt -= width / 2; break;
                case App.TextAlignOption.END: lt -= width; break;
            }
            switch (style.baseline) {
                case App.VerticalAlignOption.MIDDLE: tp -= height / 2; break;
                case App.VerticalAlignOption.BOTTOM: tp -= height; break;
            }
            return {
                x: lt, y: tp, width: width, height: height
            }
        },
        style: {
            transform: [], 
            font: "12px arial", 
            x: 0, 
            y: 0, 
            text: "默认文字",
            shadow: "0 0 0 black",
            stroke: "", 
            fill: "black", 
            align: App.TextAlignOption.START, 
            baseline: App.VerticalAlignOption.TOP, 
            opacity: 1 
        },
        get text() {
            return this.style.text;
        },
        set text(val) {
            this.style.text = val;
            this.getScene().nextRender();
        },
        get transform() {
            return this.style.transform;
        },
        set transform(val) {
            this.style.transform = val;
            this.getScene().nextRender();
        },
        get font() {
            return this.style.font;
        },
        set font(val) {
            this.style.font = val;
            this.getScene().nextRender();
        },
        get x() {
            return this.style.x;
        },
        set x(val) {
            this.style.x = val;
            this.getScene().nextRender();
        },
        set y(val) {
            this.style.y = val;
            this.getScene().nextRender();
        },
        get y() {
            return this.style.y;
        },
        set shadow(val) {
            this.style.shadow = val;
            this.getScene().nextRender();
        },
        get shadow() {
            return this.style.shadow;
        },
        get stroke() {
            return this.style.stroke;
        },
        set stroke(val) {
            this.style.stroke = val;
            this.getScene().nextRender();
        },
        get fill() {
            return this.style.fill;
        },
        set fill(val) {
            this.style.fill = val;
            this.getScene().nextRender();
        },
        get align() {
            return this.style.align;
        },
        set align(val) {
            this.style.align = val;
            this.getScene().nextRender();
        },
        get baseline() {
            return this.style.baseline;
        },
        set baseline(val) {
            this.style.baseline = val;
            this.getScene().nextRender();
        },
        get opacity() {
            return this.style.opacity;
        },
        set opacity(val) {
            this.style.opacity = val;
            this.getScene().nextRender();
        }
    })
})